'use client';

import { useRouter } from 'next/navigation';
import { useActionState, useEffect, useState } from 'react';
import { FoxButton } from '@fox/core/components/fox-button';
import { FoxButtonGroup } from '@fox/core/components/fox-button-group';
import { FoxButtonPanel } from '@fox/core/components/fox-button-panel';
import { FoxCard } from '@fox/core/components/fox-card';
import { FoxDescriptionList } from '@fox/core/components/fox-description-list';
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
import { FoxInput } from '@fox/core/components/fox-input';
import { FoxPageHeader } from '@fox/core/components/fox-page-header';
import { FoxSelect } from '@fox/core/components/fox-select';
import { submitFormAction } from '@/app/_hooks/submit-form-action';
import { useBlockingAction } from '@/app/_hooks/use-blocking-action';
import { useFeedback } from '@/app/_hooks/use-feedback';
import type { CommonCode } from '@/lib/domain/common-code';
import {
  MERCHANT_DETAIL_VISIBILITY_OPTIONS,
  MERCHANT_VOUCHER_USE_OPTIONS,
  formatMerchantDetailStatusLabel,
  formatOptionalValue,
  type MerchantDetail,
  type MerchantDetailSummary,
} from '@/lib/domain/merchant-detail';
import {
  CLOSED_DAYS_MAX_LENGTH,
  DESCRIPTION_MAX_LENGTH,
  INITIAL_MERCHANT_DETAIL_FORM_STATE,
  SORT_ORDER_MAX,
} from '@/lib/domain/merchant-detail-form';
import { MERCHANT_DETAILS_PATH, merchantDetailPath } from '@/lib/domain/merchant-detail-query';
import type { MerchantProduct } from '@/lib/domain/merchant-product';
import { formatPhoneNumber } from '@/lib/domain/phone-number';
import {
  deleteMerchantDetailAction,
  saveMerchantDetailAction,
  updateMerchantDetailVisibilityAction,
} from '../../_actions';
import { MerchantChoiceChips } from '../../_components/merchant-choice-chips';
import { MerchantImageField } from '../../_components/merchant-image-field';
import { MerchantProductTable } from '../../_components/merchant-product-table';
import styles from './merchant-detail-form.module.scss';

interface MerchantDetailFormProps {
  /** 상세가 있는 가맹점 — 고친다. */
  detail?: MerchantDetail;
  /** 상세가 아직 없는데 가맹점은 정해진 경우(행의 [수정]) — 그 가맹점에 처음 만든다. */
  merchant?: MerchantDetailSummary;
  /** 가맹점도 정해지지 않은 경우([+ 업체 등록]) — 업체명 자리에서 여기서 하나를 고른다. */
  candidates?: MerchantDetailSummary[];
  /** 선택지 중 미리 골라 둘 가맹점(`?frcsNo=`). */
  initialFrcsNo?: string;
  products?: MerchantProduct[];
  categories: CommonCode[];
}

/**
 * 가맹몰 상세 — 기획 BO-MAL-002(등록)·003(수정)을 한 화면으로 합쳤다(사용자 확정). `detail`이
 * 있으면 상세가 이미 있는 가맹점, `merchant`면 상세가 없는 정해진 가맹점, 둘 다 없으면 업체명
 * 자리에서 가맹점을 고른다. 처음 저장하면 그 가맹점 주소로 옮겨 가되 화면 구성은 그대로라 바로
 * 메뉴를 붙일 수 있고, 이후 저장은 그 자리에 머문다.
 *
 * 업체명·연락처·우편번호·주소는 가맹점 원본이라 읽기 전용이고, 기획의 [주소 검색]은 가맹점 관리
 * 화면의 것이라 여기서는 값을 바꾸지 않는다.
 */
export function MerchantDetailForm({
  detail,
  merchant: fixedMerchant,
  candidates = [],
  initialFrcsNo,
  products = [],
  categories,
}: MerchantDetailFormProps) {
  const router = useRouter();
  const { showAlert, hideAlert, showToast } = useFeedback();
  const [isBusy, startAction] = useBlockingAction();
  const [state, formAction, isPending] = useActionState(
    saveMerchantDetailAction,
    INITIAL_MERCHANT_DETAIL_FORM_STATE
  );
  const isEdit = detail !== undefined;
  const errors = state.status === 'error' ? (state.errors ?? {}) : {};

  // 가맹점이 정해져 있으면(상세가 있든 없든) 업체명은 읽기 전용이고, 아니면 여기서 고른다.
  const pinned: MerchantDetailSummary | null = detail ?? fixedMerchant ?? null;
  const [frcsNo, setFrcsNo] = useState(pinned?.id ?? initialFrcsNo ?? '');
  const merchant: MerchantDetailSummary | null =
    pinned ?? candidates.find((row) => row.id === frcsNo) ?? null;
  const [categoryCode, setCategoryCode] = useState(detail?.categoryCode ?? '');
  const [visibility, setVisibility] = useState<string[]>([
    detail?.isVisible === false ? 'N' : 'Y',
  ]);
  const [voucherUse, setVoucherUse] = useState<string[]>(['Y']);

  useEffect(() => {
    if (state.status !== 'success') return;
    if (state.created) {
      showToast({ variant: 'success', message: '등록했습니다. 이어서 메뉴를 추가할 수 있습니다.' });
      router.replace(merchantDetailPath(state.frcsNo));
    } else {
      showToast({ variant: 'success', message: '저장했습니다.' });
      router.refresh();
    }
  }, [state, router, showToast]);

  function toggleVisibility() {
    if (!detail) return;
    const next = detail.isVisible === false;
    startAction(async () => {
      const result = await updateMerchantDetailVisibilityAction(detail.id, next);
      showToast(
        result.status === 'error'
          ? { variant: 'danger', message: result.message }
          : { variant: 'success', message: next ? '노출로 바꿨습니다.' : '비활성으로 바꿨습니다.' }
      );
    });
  }

  function runDelete() {
    if (!detail) return;
    hideAlert();
    startAction(async () => {
      const result = await deleteMerchantDetailAction(detail.id);
      if (result.status === 'error') {
        showToast({ variant: 'danger', message: result.message });
        return;
      }
      showToast({ variant: 'success', message: '삭제했습니다.' });
      router.push(MERCHANT_DETAILS_PATH);
    });
  }

  function confirmDelete() {
    if (!detail) return;
    showAlert({
      variant: 'danger',
      title: '가맹몰 상세를 삭제하시겠습니까?',
      message: `"${detail.name}"의 상세 정보를 삭제합니다. 삭제 후에는 되돌릴 수 없습니다.`,
      actions: (
        <FoxButtonGroup size="md">
          <FoxButton type="default" size="md" label="취소" onAction={hideAlert} />
          <FoxButton type="primary" size="md" label="삭제" onAction={runDelete} />
        </FoxButtonGroup>
      ),
    });
  }

  return (
    <>
      <FoxPageHeader
        title="가맹몰 상세 정보"
        description="지역상생몰에 노출할 업체의 상세를 등록·수정한다. 저장 즉시 앱에 반영된다"
        breadcrumb={[
          { label: '홈', href: '/' },
          { label: '관리자관리' },
          { label: '가맹몰 상세 관리', href: MERCHANT_DETAILS_PATH },
          { label: '상세 정보' },
        ]}
      />

      <form
        id="merchant-detail-form"
        onSubmit={(event) => submitFormAction(event, formAction)}
        className={styles.form}
      >
        <input type="hidden" name="frcsNo" value={frcsNo} />
        <input type="hidden" name="mode" value={isEdit ? 'edit' : 'create'} />

        <FoxCard size="lg" title="기본 정보" className={styles.section}>
          <div className={styles.grid}>
            <div className={styles.fieldWide}>
              {pinned ? (
                <FoxInput size="md" label="업체명" requirement="required" value={pinned.name} readOnly state="view" />
              ) : (
                <>
                  <FoxSelect
                    size="md"
                    label="업체명"
                    requirement="required"
                    placeholder="상세를 등록할 가맹점 선택"
                    options={candidates.map((row) => ({ value: row.id, label: row.name }))}
                    value={frcsNo}
                    onValueChange={setFrcsNo}
                    error={Boolean(errors.frcsNo)}
                  />
                  {errors.frcsNo && <FoxHelperText type="danger" message={errors.frcsNo} />}
                  {candidates.length === 0 && (
                    <FoxHelperText
                      type="information"
                      message="상세를 붙일 가맹점이 없습니다. 가맹점 관리에서 먼저 등록해 주세요."
                    />
                  )}
                </>
              )}
            </div>
            <div className={styles.field}>
              <FoxSelect
                size="md"
                label="카테고리"
                requirement="required"
                placeholder="선택"
                options={categories.map((code) => ({ value: code.code, label: code.label }))}
                value={categoryCode}
                onValueChange={setCategoryCode}
                error={Boolean(errors.categoryCode)}
              />
              <input type="hidden" name="categoryCode" value={categoryCode} />
              {errors.categoryCode && <FoxHelperText type="danger" message={errors.categoryCode} />}
            </div>
            <div className={styles.field}>
              <FoxInput
                size="md"
                label="업체 연락처"
                requirement="required"
                value={formatOptionalValue(formatPhoneNumber(merchant?.phoneNumber ?? null))}
                readOnly
                state="view"
              />
            </div>
          </div>

          <div className={styles.grid}>
            <div className={styles.fieldNarrow}>
              <FoxInput size="md" label="우편번호" requirement="required" value={formatOptionalValue(detail?.postalCode)} readOnly state="view" />
            </div>
            <div className={styles.fieldWide}>
              <FoxInput size="md" label="주소" value={formatOptionalValue(merchant?.address)} readOnly state="view" />
            </div>
            <div className={styles.field}>
              <FoxInput size="md" label="상세주소" value={formatOptionalValue(merchant?.addressDetail)} readOnly state="view" />
            </div>
          </div>

          <div className={styles.grid}>
            <div className={styles.fieldWide}>
              <FoxInput
                size="md"
                name="description"
                label="한줄 소개"
                placeholder="앱 목록·상세에 노출되는 한 줄 설명"
                defaultValue={detail?.description ?? ''}
                maxLength={DESCRIPTION_MAX_LENGTH}
                invalid={Boolean(errors.description)}
                message={errors.description}
              />
            </div>
            <div className={styles.fieldNarrow}>
              <FoxInput
                size="md"
                name="openTime"
                type="time"
                label="영업 시작"
                defaultValue={detail?.openTime ?? ''}
                invalid={Boolean(errors.openTime)}
                message={errors.openTime}
              />
            </div>
            <div className={styles.fieldNarrow}>
              <FoxInput
                size="md"
                name="closeTime"
                type="time"
                label="영업 종료"
                defaultValue={detail?.closeTime ?? ''}
                invalid={Boolean(errors.closeTime)}
                message={errors.closeTime}
              />
            </div>
            <div className={styles.field}>
              <FoxInput
                size="md"
                name="closedDays"
                label="휴무일"
                placeholder="예) 매주 월요일"
                defaultValue={detail?.closedDays ?? ''}
                maxLength={CLOSED_DAYS_MAX_LENGTH}
                invalid={Boolean(errors.closedDays)}
                message={errors.closedDays}
              />
            </div>
          </div>

          <div className={styles.grid}>
            <MerchantChoiceChips
              label="노출 상태"
              name="isVisible"
              required
              options={MERCHANT_DETAIL_VISIBILITY_OPTIONS}
              values={visibility}
              onChange={setVisibility}
            />
            <MerchantChoiceChips
              label="바우처 사용"
              name="isVoucherUsable"
              required
              options={MERCHANT_VOUCHER_USE_OPTIONS}
              values={voucherUse}
              onChange={setVoucherUse}
            />
            <div className={styles.fieldNarrow}>
              <FoxInput
                size="md"
                name="sortOrder"
                type="number"
                inputMode="numeric"
                min={0}
                max={SORT_ORDER_MAX}
                label="노출 순서"
                placeholder="숫자 (낮을수록 상단)"
                defaultValue={detail?.sortOrder == null ? '' : String(detail.sortOrder)}
                invalid={Boolean(errors.sortOrder)}
                message={errors.sortOrder}
              />
            </div>
          </div>
        </FoxCard>

        <FoxCard
          size="lg"
          title="이미지 등록"
          description="대표 1장 필수 · 추가 최대 11장 (앱 슬라이더 최대 12장)"
          className={styles.section}
        >
          {/* 저장으로 파일 id가 바뀌면 다시 마운트해 칸 상태를 서버 값으로 되돌린다. */}
          <MerchantImageField
            key={`${detail?.thumbnailFileId ?? ''}/${detail?.imageFileId ?? ''}`}
            defaultThumbnailUrl={detail?.thumbnailUrl ?? null}
            retainedThumbnailId={detail?.thumbnailFileId ?? null}
            defaultImageUrls={detail?.imageUrls ?? []}
            retainedImageFileId={detail?.imageFileId ?? null}
            thumbnailError={errors.thumbnail}
            imagesError={errors.images}
          />
        </FoxCard>

        <FoxCard
          size="lg"
          title="메뉴 정보"
          description="앱 상세 화면의 메뉴 목록에 노출된다"
          className={styles.section}
        >
          <MerchantProductTable frcsNo={frcsNo} products={products} canAdd={isEdit} />
        </FoxCard>

        {detail && (
          <FoxCard size="lg" title="등록 정보" className={styles.section}>
            <FoxDescriptionList
              layout="inline"
              items={[
                { key: 'registeredAt', term: '등록일시', description: formatOptionalValue(detail.registeredAt) },
                { key: 'registeredBy', term: '등록자', description: formatOptionalValue(detail.registeredBy) },
                {
                  key: 'modified',
                  term: '최종 수정',
                  description: [detail.modifiedAt, detail.modifiedBy]
                    .filter((value): value is string => Boolean(value))
                    .join(' / ') || '-',
                },
                { key: 'status', term: '현재 상태', description: formatMerchantDetailStatusLabel(detail) },
              ]}
            />
          </FoxCard>
        )}

        {state.status === 'error' && state.message && (
          <FoxHelperText type="danger" message={state.message} />
        )}

        <FoxButtonPanel>
          <FoxButtonGroup size="lg">
            {detail && (
              <>
                <FoxButton type="default" size="lg" label="삭제" disabled={isBusy} onAction={confirmDelete} />
                <FoxButton
                  type="default"
                  size="lg"
                  label={detail.isVisible === false ? '노출' : '비활성'}
                  disabled={isBusy}
                  onAction={toggleVisibility}
                />
              </>
            )}
            <FoxButton
              type="default"
              size="lg"
              label="취소"
              onAction={() => router.push(MERCHANT_DETAILS_PATH)}
            />
            <FoxButton
              type="primary"
              size="lg"
              htmlType="submit"
              label={isEdit ? '저장' : '등록'}
              loading={isPending}
            />
          </FoxButtonGroup>
        </FoxButtonPanel>
      </form>
    </>
  );
}
